package com.boss.salary.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boss.common.entity.WfActionDTO;
import com.boss.common.enums.ActionTypeEnum;
import com.boss.common.service.ICommonService;
import com.boss.common.util.DateUtils;
import com.boss.salary.constant.SystemDictConstant;
import com.boss.salary.dao.IAgencyVerifyDao;
import com.boss.salary.dao.IGenerateSalaryDataDao;
import com.boss.salary.entity.AgencyVerify;
import com.boss.salary.entity.MakeSalaryData;
import com.boss.salary.entity.SalaryPaymentRequisitionBack;
import com.boss.salary.service.IPaymentAsyncService;
import com.boss.salary.service.IRedisService;
import com.boss.salary.workflow.service.ISalaryWorkFlowService;
import com.boss.sys.ca.user.dto.UserDTO;
import com.boss.sys.utils.SysUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@EnableAsync
public class PaymentAsyncServiceImpl implements IPaymentAsyncService{

    private static final Logger logger = LoggerFactory.getLogger(PaymentAsyncServiceImpl.class);
    @Autowired
    private ICommonService iCommonService;
    @Autowired
    private IRedisService   redisService;
    @Autowired
    private IGenerateSalaryDataDao iGenerateSalaryDataDao;
    @Autowired
    private IAgencyVerifyDao agencyVerifyDao;
    @Autowired
    private ISalaryWorkFlowService iSalaryWorkFlowService;

    @Async
    @Override
    public void sentPayMentAsyncForSeate(List<Map<String, Object>> payList, UserDTO userDto, MakeSalaryData makeSalaryData, String tokenid, String uuid,List<String> totalAgencyIds) {

        StringBuffer requestMessage=new StringBuffer();
        String paymentCreateTime=String.valueOf(DateUtils.getCurrentTimeStamp());//生成支付时间
        int total= totalAgencyIds.size();
        DecimalFormat df=new DecimalFormat("0.00");
        for(int i=0;i<total;i++){
            List<Map<String, Object>> payListOneAgency=new ArrayList<>();
            for(Map<String, Object> map:payList){
                if(totalAgencyIds.get(i).equals(map.get("agency_id"))) {
                    payListOneAgency.add(map);
                }
            }
            logger.info(totalAgencyIds.get(i)+"=======走单个单位生成支付异步方法==============");
            toPayment(payListOneAgency,userDto,makeSalaryData,tokenid,totalAgencyIds.get(i),requestMessage,paymentCreateTime); //调用生成支付方法
            redisService.put(uuid,df.format((float)(i+1)/total));
            logger.info(totalAgencyIds.get(i)+"=======走单个单位生成支付异步方法结束==============");
        }
        if(StringUtils.isEmpty(requestMessage.toString())) {
            redisService.put(uuid, "S");
            redisService.del(userDto.getProvince()+"generateSalary");
        }else{
            redisService.put(uuid,requestMessage.toString());
            redisService.del(userDto.getProvince()+"generateSalary");
        }


    }
    @Override
    @GlobalTransactional(timeoutMills=300000)//@Transactional(rollbackFor = Exception.class)
    public  void toPayment(List<Map<String, Object>> payListOneAgency, UserDTO userDto, MakeSalaryData makeSalaryData, String tokenid,String agencyId,StringBuffer requestMessage, String paymentCreateTime){
        JSONArray jsonArray =new JSONArray();
        Map<String,String> map= iCommonService.sentPayMent(payListOneAgency, tokenid);//每个单位单独走数据
        JSONObject result = JSONObject.parseObject(map.get("result"));
        String rscode = result.getString("rscode");
        List<String> agencyIds=new ArrayList<>();//反写需要走工作流的单位id
        List<String> payidList=new ArrayList<>();//接成功生成支付得申请id,备用工作流后续流程调用异常时作废申请用
        agencyIds.add(agencyId);
        // 调用成功
        if ("200".equals(rscode)) {//将成功的数据单位id保存在集合中，后续处理
            try{
                jsonArray.addAll(result.getJSONArray("data"));
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    // 修改表状态，并添加模拟值
                    payidList.add(jsonObject.getString("id"));
                }
                savePayBackDatas(jsonArray,userDto,agencyIds,paymentCreateTime);// 保存回单数据
                makeSalaryData.setAgencyIds(agencyIds);
                doSalaryFlow(makeSalaryData, userDto);//执行工作流
            }catch (Exception e){
                logger.info("支付生成后，后续方法错误：",e);
//                if(!StringUtils.isEmpty(payidList)) {//报错时若申请支付id不为空则作废支付申请
//                    iCommonService.nullifyPayMent(payidList, tokenid);
//                }
            }
        } else {
            logger.info("存在生成失败信息："+result.getString("result"));
            requestMessage.append("F-"+result.getString("result")+"\n");
        }

    }


    /**
     * 保存支付回单数据
     * @param jsonArray
     */

    private void savePayBackDatas(JSONArray jsonArray, UserDTO userDto, List<String> agencyIds,String paymentCreateTime) {
        List<SalaryPaymentRequisitionBack> salaryPaymentRequisitionBacks=new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            // 修改表状态，并添加模拟值
            String agencyId = jsonObject.getString("agency_id");
            SalaryPaymentRequisitionBack salaryPaymentRequisitionBack = new SalaryPaymentRequisitionBack();
            salaryPaymentRequisitionBack.setId(SysUtils.generateGuid());
            salaryPaymentRequisitionBack.setCreateTime(String.valueOf(DateUtils.getCurrentTimeStamp()));
            salaryPaymentRequisitionBack.setUpdateTime(String.valueOf(DateUtils.getCurrentTimeStamp()));
            salaryPaymentRequisitionBack.setAgencyId(agencyId);
            salaryPaymentRequisitionBack.setAgencyName(jsonObject.getString("agency_name"));
            salaryPaymentRequisitionBack.setPayId(jsonObject.getString("id"));
            salaryPaymentRequisitionBack.setPayAppNo(jsonObject.getString("pay_app_no"));
            salaryPaymentRequisitionBack.setBgtId(jsonObject.getString("bgt_id"));
            salaryPaymentRequisitionBack.setPayAppAmt(jsonObject.getString("pay_app_amt"));
            salaryPaymentRequisitionBack.setFundType(jsonObject.getString("fund_type"));
            salaryPaymentRequisitionBack.setPayeeAcctName(jsonObject.getString("payee_acct_name"));
            salaryPaymentRequisitionBack.setPayeeAcctNo(jsonObject.getString("payee_acct_no"));
            salaryPaymentRequisitionBack.setPayeeAcctBankName(jsonObject.getString("payee_acct_bank_name"));
            salaryPaymentRequisitionBack.setPayType(jsonObject.getString("pay_type"));
            salaryPaymentRequisitionBack.setProCat(jsonObject.getString("pro_cat"));
            salaryPaymentRequisitionBack.setGovBgtEco(jsonObject.getString("gov_bgt_eco"));
            salaryPaymentRequisitionBack.setDepBgtEco(jsonObject.getString("dep_bgt_eco"));
            salaryPaymentRequisitionBack.setPro(jsonObject.getString("pro"));
            salaryPaymentRequisitionBack.setUseName(jsonObject.getString("use_"));
            salaryPaymentRequisitionBack.setExpFunc(jsonObject.getString("exp_func"));
            salaryPaymentRequisitionBack.setMofDivCode(userDto.getProvince());
            salaryPaymentRequisitionBack.setIsDeleted(SystemDictConstant.IS_FALSE);
            salaryPaymentRequisitionBacks.add(salaryPaymentRequisitionBack);
        }
        iGenerateSalaryDataDao.updatePayDatas(agencyIds, String.valueOf(SystemDictConstant.IS_TRUE),paymentCreateTime);
        iGenerateSalaryDataDao.batchInsertPayBackData(salaryPaymentRequisitionBacks);
    }

    /**
     * 生成支付数据工作流
     * @param makeSalaryData
     * @param userDto
     */
    private void doSalaryFlow(MakeSalaryData makeSalaryData, UserDTO userDto) {

        List<AgencyVerify> agencyVerify1s = agencyVerifyDao.getAgencyVerifyByAgencyIds(makeSalaryData.getAgencyIds());
        // 单位上报录入流程
        WfActionDTO<List<AgencyVerify>> wfActionDTO = new WfActionDTO();
        wfActionDTO.setBizDatas(agencyVerify1s);
        wfActionDTO.setMenuguid(makeSalaryData.getMenuid());
        // 审核
        wfActionDTO.setActionType(ActionTypeEnum.WF_AUDIT.getActionTypeCode());
        wfActionDTO.setBizKeyName("bizKey");
        iSalaryWorkFlowService.doSalaryFlowList(userDto,wfActionDTO);
        logger.info("==== 工作流生成工资数据完毕End  ===");
    }
}
